/*
 *  Copyright (C) 2010 JS.MinecraftSavior
 *
 *  This file is part of the Minecraft Savior utility.
 *
 *  Minecraft Savior is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Minecraft Savior is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.utility.MinecraftSavior.file;

import com.utility.MinecraftSavior.ui.MCS;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Compress {
    private static final int BUFFER_SIZE = 8192;

    public static void compressDir(String dirStr, String zipName)
            throws IOException {

        // Initialize zip we're going to make
        ZipOutputStream zOut = new ZipOutputStream(new FileOutputStream(zipName));
        zOut.setMethod(ZipOutputStream.DEFLATED);

        // Process all sub-directories and files
        doDirsAndFiles(dirStr, zOut, "");

        // Close the zip
        zOut.close();
    }

    private static void doDirsAndFiles(String dirStr, ZipOutputStream zOut, String path)
            throws IOException {

        // Store directory that will be compressed
        File dirToBeCompressed = new File(dirStr);

        // Get list of directories from dirToBeCompressed directory
        String[] dirs = dirToBeCompressed.list();

        // Initialize dataBuffer and numBytesRead for IO
        int numBytesRead = 0;
        byte[] dataBuffer = new byte[BUFFER_SIZE];

        // Process each file or directory in current directory
        for (int i = 0; i < dirs.length; i++) {
            File curFile = new File(dirToBeCompressed, dirs[i]);

            // If curFile is directory, process all files/sub-directories
            if (curFile.isDirectory()) {
                doDirsAndFiles(curFile.getPath(), zOut, path + curFile.getName()
                        + File.separator);
                continue;
            }

            // Display output for user within the backupStatusTextArea
            MCS.updateBackupStatusTextArea("\tCompressing: " + path + curFile.getName());

            // Initialize buffered input stream to curFile
            BufferedInputStream src = new BufferedInputStream
                    (new FileInputStream(curFile), BUFFER_SIZE);

            // Prepare for writing a new zip entry
            zOut.putNextEntry(new ZipEntry(path + curFile.getName()));

            // Write what is read from input stream to zip output stream
            while ((numBytesRead = src.read(dataBuffer, 0, BUFFER_SIZE)) != -1)
                zOut.write(dataBuffer, 0, numBytesRead);

            // Close input stream
            src.close();
        }
    }
}
